package com.liu.qqRobot.wm.handler;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.liu.common.utils.HtmlToImageUtils;
import com.liu.common.utils.QQClientUtils;
import com.liu.common.utils.WmClientUtils;
import com.liu.mybatisPlus.q.service.QGroupUserOperationQuantityService;
import com.liu.mybatisPlus.wm.entity.base.WmItem;
import com.liu.mybatisPlus.wm.entity.base.WmItemKeyWord;
import com.liu.mybatisPlus.wm.service.WmItemKeyWordService;
import com.liu.mybatisPlus.wm.service.WmItemService;
import com.liu.qqRobot.event.entity.dto.EventReportingDTO;
import com.liu.qqRobot.q.enums.OperationTypeEnum;
import com.liu.qqRobot.wm.entity.dto.WarframeMarketItemsOrderDTO;
import com.liu.qqRobot.wm.entity.dto.WarframeMarketItemsOrderTemplateDTO;
import freemarker.template.TemplateException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class WmHandler {

    @Resource
    private WmItemService wmItemService;

    @Resource
    private WmItemKeyWordService wmItemKeyWordService;

    @Resource
    private QGroupUserOperationQuantityService qGroupUserOperationQuantityService;

    /**
     * 处理事件
     * @param data 信息内容
     * @param groupId 群号
     * @param userId 发送人QQ号
     */
    public void handler(EventReportingDTO.Message.Data data, Long groupId, Long userId, Boolean isGroup) {
        Integer page = 1;
        String text = data.getText();
        // 判断是否满级
        boolean isMax = false;
        if (text.contains("满级")) {
            isMax = true;
            text = text.replace("满级", "");
        }

        String[] textSplit = text.split(" ");

        // 匹配查询的物品
        WmItem wmItem = null;
        String itemName = textSplit[textSplit.length - 1];
        QueryWrapper<WmItemKeyWord> wmItemKeyWordQueryWrapper = new QueryWrapper<>();
        wmItemKeyWordQueryWrapper.eq("key_word", itemName);
        WmItemKeyWord wmItemKeyWord = wmItemKeyWordService.getOne(wmItemKeyWordQueryWrapper);
        if (wmItemKeyWord != null) {
            wmItem = wmItemService.getById(wmItemKeyWord.getId());
        } else {
            QueryWrapper<WmItem> wmItemQueryWrapper = new QueryWrapper<>();
            wmItemQueryWrapper.eq("item_name", itemName);
            wmItem = wmItemService.getOne(wmItemQueryWrapper);
        }
        if (wmItem == null) {
            return;
        }
        this.initMsgAndSend(wmItem, userId, groupId, "sell", page, isGroup, isMax);
    }

    /**
     * 初始化发送的信息并发送
     * @param wmItem wmItem
     * @param userId 发送人QQ号
     * @param groupId 群号
     * @param orderType 订单类型 sell-想要卖 buy-想要买
     * @param page 页数
     */
    private void initMsgAndSend(WmItem wmItem, Long userId, Long groupId, String orderType, Integer page, Boolean isGroup, Boolean isMax) {
        List<WarframeMarketItemsOrderDTO> warframeMarketItemsOrderDTOList = WmClientUtils.getItemOrders(wmItem.getUrlName());
        // 过滤订单类型
        warframeMarketItemsOrderDTOList = warframeMarketItemsOrderDTOList.stream()
                .filter(w -> w.getOrderType().equals(orderType)).collect(Collectors.toList());
        // 判断是否满级
        if (isMax) {
            warframeMarketItemsOrderDTOList = warframeMarketItemsOrderDTOList.stream()
                    .filter(w -> Objects.equals(w.getModRank(), wmItem.getModMaxRank())).collect(Collectors.toList());
        }
        // 判断排序
        warframeMarketItemsOrderDTOList.forEach(warframeMarketItemsOrderDTO -> {
            warframeMarketItemsOrderDTO.setSort(this.getSortByStatus(warframeMarketItemsOrderDTO.getUser().getStatus()));
        });
        // 排序 ingame-1 online-2 offline-3，后排序价格
        warframeMarketItemsOrderDTOList = warframeMarketItemsOrderDTOList.stream()
                .sorted(Comparator.comparing(WarframeMarketItemsOrderDTO::getSort).thenComparing(WarframeMarketItemsOrderDTO::getPlatinum))
                .collect(Collectors.toList());
        List<List<WarframeMarketItemsOrderDTO>> split = ListUtil.split(warframeMarketItemsOrderDTOList, 5);
        List<WarframeMarketItemsOrderTemplateDTO> warframeMarketItemsOrderTemplateDTOS = new ArrayList<>();
        StringBuilder firstOrderMsg = new StringBuilder("/w ");
        StringBuilder totalSellerName = new StringBuilder("本页所有卖家游戏名称：");
        for (int i = 0; i < split.size(); i++) {
            List<WarframeMarketItemsOrderDTO> warframeMarketItemsOrderDTOS = split.get(page - 1);
            for (int i1 = 0; i1 < warframeMarketItemsOrderDTOS.size(); i1++) {
                WarframeMarketItemsOrderDTO warframeMarketItemsOrderDTO = warframeMarketItemsOrderDTOS.get(i1);
                if (i1 == 0) {
                    firstOrderMsg.append(warframeMarketItemsOrderDTO.getUser().getIngameName())
                            .append(" Hi! I want to buy: ").append(wmItem.getUrlName().replace("_", " "))
                            .append(" for ").append(warframeMarketItemsOrderDTO.getPlatinum()).append(" platonum.");
                }
                totalSellerName.append("【").append(warframeMarketItemsOrderDTO.getUser().getIngameName()).append("】");
                WarframeMarketItemsOrderTemplateDTO warframeMarketItemsOrderTemplateDTO = new WarframeMarketItemsOrderTemplateDTO();
                warframeMarketItemsOrderTemplateDTO.setQuantity(String.valueOf(warframeMarketItemsOrderDTO.getQuantity()));
                warframeMarketItemsOrderTemplateDTO.setPlatinum(String.valueOf(warframeMarketItemsOrderDTO.getPlatinum()));
                warframeMarketItemsOrderTemplateDTO.setStatus(this.getStatusDesc(warframeMarketItemsOrderDTO.getUser().getStatus()));
                warframeMarketItemsOrderTemplateDTO.setIngameName(warframeMarketItemsOrderDTO.getUser().getIngameName());
                warframeMarketItemsOrderTemplateDTO.setModRank(warframeMarketItemsOrderDTO.getModRank() != null ? String.valueOf(warframeMarketItemsOrderDTO.getModRank()):null);
                warframeMarketItemsOrderTemplateDTOS.add(warframeMarketItemsOrderTemplateDTO);
            }
            break;
        }
        if (CollUtil.isEmpty(warframeMarketItemsOrderTemplateDTOS)) {
            String msg = "[CQ:at,qq=" + userId + "]\n目前未在warframe.market查询到相关交易";
            QQClientUtils.sendMsg(msg, userId, groupId, isGroup);
            return;
        }
        Map<String, Object> templateParam = new HashMap<>();
        String baseName = wmItem.getItemName();
        if (isMax) {
            baseName = "满级" + baseName;
        }
        templateParam.put("baseName", baseName);
        templateParam.put("orderList", warframeMarketItemsOrderTemplateDTOS);
        try {
            HtmlToImageUtils.htmlToImage("orderTemplate.html", templateParam,
                    "src/main/resources/picture/order.png", 2000);
            File file = new File("src/main/resources/picture/order.png");
            String encode = Base64.encode(file);
            String msg = "[CQ:at,qq=" + userId + "]\n[CQ:image,file=base64://" + encode+ ",type=show,subType=0]";
            QQClientUtils.sendMsg(msg + firstOrderMsg + "\n" + totalSellerName, userId, groupId, isGroup);
            qGroupUserOperationQuantityService.statisticsOperationQuantityByType(groupId, userId, OperationTypeEnum.WM);
        } catch (IOException | ParserConfigurationException | SAXException | TemplateException e) {
            log.error("获取订单展示模板失败:{}", e.getMessage(), e);
//            QQClientUtils.sendGroupMsg("[CQ:at,qq=" + userId + "]\n获取订单展示模板失败，请联系制作人", userId, groupId, isGroup);
        }
    }

    /**
     * 解析状态为中文
     * @param status offline ingame online
     * @return String
     */
    private String getStatusDesc(String status) {
        return switch (status) {
            case "offline" -> "离线";
            case "ingame" -> "游戏中";
            case "online" -> "在线";
            default -> "";
        };
    }

    /**
     * 解析状态判断排序
     * @param status offline ingame online
     * @return String
     */
    private Integer getSortByStatus(String status) {
        return switch (status) {
            case "offline" -> 3;
            case "ingame" -> 1;
            case "online" -> 2;
            default -> 4;
        };
    }

}
